import React, { Suspense } from 'react';
// import { Router, Switch, Route, Redirect } from 'react-router';
import routeList from './routerList';
import {
  HashRouter as Router,
  Switch,
  Route,
  Redirect,
} from 'react-router-dom';

interface RouteProps {
  redirect?: Redirect;
  path?: string | undefined;
  exact?: boolean;
  component: React.ComponentClass<any, any>;
  key: any;
  children?: RouteConfig[];
}
interface RouteConfig {
  component: any;
  children?: RouteConfig[];
  path?: string | undefined;
}
const LoadingFallback = () => (
  <div style={{ paddingTop: 200, textAlign: 'center' }}>Loading...</div>
);

const RouteItem = (props: RouteProps) => {
  const { redirect, path, exact, component: RouteComponent, key, children } = props;
  if (redirect) {
    return <Redirect exact key={key} from={path} to={redirect} />;
  } else if (children) {
    return (
      <RouteComponent {...props}>
        <Suspense fallback={<LoadingFallback />}>
          <Switch>
            {(children || []).map((routeChild, idx) => {
              const {
                path: childPath,
                ...childOthers
              } = routeChild;
              return RouteItem({
                ...childOthers,
                key: `${key}-${idx}`,
                path: childPath && joinPath(path, childPath),
              });
            })}
          </Switch>
        </Suspense>
      </RouteComponent>
    );
  }
  return <Route exact={exact} key={key} component={RouteComponent} path={path} />;
};

const joinPath = (...parts: Array<string | undefined>) => {
  const separator = '/';
  const replace = new RegExp(`${separator}{1,}`, 'g');
  return parts.join(separator).replace(replace, separator);
};

export default function AppRouter() {
  return (
    <Router>
      <Switch>
        <Redirect exact from="/" to="home" />
        {
          routeList.map((route: RouteConfig, index: number) => {
            const { component: RouteComponent, children, ...others } = route;
            return (
              <Route
                key={index}
                {...others}
                component={(props: RouteProps) => {
                  return children
                    ? (
                    <RouteComponent {...props}>
                      <Suspense fallback={<LoadingFallback />}>
                        <Switch>
                          {(children || []).map((routeChild, idx) => {
                            const {
                              path: childPath,
                              ...childOthers
                            } = routeChild;
                            return RouteItem({
                              ...childOthers,
                              key: `${index}-${idx}`,
                              path: childPath && joinPath(route.path, childPath),
                            });
                          })}
                        </Switch>
                      </Suspense>
                    </RouteComponent>
                      )
                    : (
                      <Suspense fallback={<LoadingFallback />}>
                        {RouteItem({
                          key: index,
                          ...route,
                        })}
                      </Suspense>
                      );
                }}
              />
            );
          })
        }
      </Switch>
    </Router>
  );
}
